package com.hfzy.ihk.web.aliyuncall.context;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alicom.mns.tools.DefaultAlicomMessagePuller;
import com.alicom.mns.tools.MessageListener;
import com.aliyun.mns.model.Message;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.common.util.uuid.base64uuid.UUIDs;
import com.hfzy.ihk.facade.aliyuncall.enums.CallTypeEnum;
import com.hfzy.ihk.facade.aliyuncall.enums.MsgTypeEnum;
import com.hfzy.ihk.web.aliyuncall.biz.AliyunAsrCallStateBiz;
import com.hfzy.ihk.web.aliyuncall.biz.AliyunCallStateBiz;
import com.hfzy.ihk.web.aliyuncall.biz.PushDataToAnalysis;
import com.hfzy.ihk.web.aliyuncall.biz.PushDataToBrowserBiz;
import com.hfzy.ihk.web.aliyuncall.constant.AliyunAkInfo;
import com.hfzy.ihk.web.aliyuncall.constant.RedisFields;
import com.hfzy.ihk.web.aliyuncall.constant.RedisKey;
import com.hfzy.ihk.web.aliyuncall.support.ColudCallUtils;
import com.hfzy.ihk.web.aliyuncall.support.websocket.WebSocketUtils;
import com.hfzy.ihk.web.aliyuncall.vo.AliyunCallState;
import com.hfzy.ihk.web.aliyuncall.vo.VoiceRTASRReportVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

//import com.google.gson.Gson;

/**
 * Created by YANFA on 2018/7/20.
 */
@Component
@DependsOn("aliyunAkInfo")
public class AliyunMsgInti  implements InitializingBean,DisposableBean {



    @Value("${aliyun.enable}")
    private String aliyun;

    public static Logger logger = LoggerFactory.getLogger(AliyunMsgInti.class);

    @Autowired
    ColudCallUtils coludCallUtils;

    @Autowired
    private   WebSocketUtils webSocketUtils;

    @Autowired
    private  AliyunCallStateBiz aliyunCallStateBiz;

    @Autowired
    private AliyunAsrCallStateBiz aliyunAsrCallStateBiz;

    @Autowired
    private  PushDataToAnalysis pushDataToAnalysis;

    @Autowired
    private  PushDataToBrowserBiz pushDataToBrowserBiz;

    @Override
    public void afterPropertiesSet() throws Exception {
        if("true".equals(aliyun)) {
            intiVoiceRTASRReport();//初始化接受asr 长连接
            intiVoiceCallReport();
        }
    }

    @Override
    public void destroy() throws Exception {

    }

    /**
     * 初始化接收呼叫中间状态消息
     */
    public  void intiVoiceCallReport(){
        try {
            DefaultAlicomMessagePuller puller = new DefaultAlicomMessagePuller();
            puller.startReceiveMsg(AliyunAkInfo.accessKeyId, AliyunAkInfo.accessKeySecret, AliyunAkInfo.VOICECALLREPORT_MESSAGE_TYPE, AliyunAkInfo.VOICECALLREPORT_QUEUENAME, message->{
                    try{
                            logger.info("消息队列接受中间状态消息："+message.getMessageBodyAsString());
                            String jsonData= message.getMessageBodyAsString();
                            if(StringTools.isNotempty(jsonData)) {
                                AliyunCallState aliyunCallState = JSONObject.parseObject(jsonData,AliyunCallState.class);
                                //通过sessionId判断是哪一种外呼状态（双呼，ASR 智能外呼）
                                String sessionId= aliyunCallState.getOut_id();
                                if(sessionId==null){
                                    logger.info("呼叫中间状态未找到seeionId,msg:{}",jsonData);
                                    return true;
                                }

                                String commitTo = coludCallUtils.getCommitTo(sessionId);
                                if(commitTo==null){
                                    logger.info("呼叫中间状态未找到commitTo,msg:{}",jsonData);
                                    return true;
                                }
                                Long start = System.currentTimeMillis();
                                if(commitTo.equals("12")) { //ASR智能外呼状态
                                    aliyunAsrCallStateBiz.dealCallState(aliyunCallState,AliyunAkInfo.VOICECALLREPORT);
                                }else{//双呼状态
                                    aliyunCallStateBiz.dealCallState(aliyunCallState, AliyunAkInfo.VOICECALLREPORT);
                                }
                                logger.info("中间状态入队时间：" + (System.currentTimeMillis() - start));
                            }
                    } catch (Throwable e) {
                            //您自己的代码部分导致的异常，应该return false,这样消息不会被delete掉，而会根据策略进行重推
                            return false;
                    }
                            //消息处理成功，返回true, SDK将调用MNS的delete方法将消息从队列中删除掉
              return true;
            });
            logger.info("初始化接收呼叫中间状态队列完成");
        }catch (Exception e){
            logger.error("初始化接收呼叫中间状态队列异常",e);
        }
    }
    /**
     * 初始化接收ASR实时消息
     */
    public  void intiVoiceRTASRReport(){
        try {
            DefaultAlicomMessagePuller puller = new DefaultAlicomMessagePuller();
            puller.startReceiveMsg(AliyunAkInfo.accessKeyId, AliyunAkInfo.accessKeySecret, AliyunAkInfo.VOICERTASRREPORT_MESSAGETYPE, AliyunAkInfo.VOICERTASRREPORT_QUEUENAME, message->{
                try{
                    if(StringTools.isNotempty(message.getMessageBodyAsString())) {
                        logger.info("---->消息队列接收ars消息："+message.getMessageBodyAsString());
                        VoiceRTASRReportVo voiceRTASRReportVo = JSONObject.parseObject(message.getMessageBodyAsString(),VoiceRTASRReportVo.class);
                        //判断是哪一种呼叫的消息
                        String sesionId = voiceRTASRReportVo.getOut_id();

                        if(StringTools.isEmpty(sesionId)) {
                            logger.info("----->消息队列接收ars消息，获取sessionId异常："+message.getMessageBodyAsString());
                            return true;
                        }

                        String[] arg = pushDataToAnalysis.readPackageIdAndCallTaskId(voiceRTASRReportVo.getOut_id());
                        //判断如果是保利测试生成的数据则不进行推送
                        if(arg==null||arg.length<2){
                            return true;
                        }
                        logger.info("-------------->获得arg length:"+arg.length);

                        //自定义生成本句内容的Id
                        voiceRTASRReportVo.setWordId(UUIDs.base64UUID());

                        //填写推送代码 获取callTaskId 和 packageId
                        logger.info("---->packageId:{},callTaskId:{},",arg[0],arg[1]);
                        //双呼语音识别消息

                        //根据sessionId推送到客户端
                        Long start =System.currentTimeMillis();
                        //推送浏览器
                        try {
                            pushDataToBrowserBiz.pushAsrToBrowser(voiceRTASRReportVo, CallTypeEnum.DOUBLE_CALL.getValue()); //异步
                        }catch (Exception e){
                            logger.error("--------->推送识别结果到浏览器异常，sessionId:{}",voiceRTASRReportVo.getOut_id(),e);
                        }
                        logger.info("将words推送浏览器 入队时间："+(System.currentTimeMillis()-start));

                        //进推送队列推送
                        Long start1 =System.currentTimeMillis();
                        try {
                            pushDataToAnalysis.pushData(arg[0], arg[1], voiceRTASRReportVo.getOut_id(),  voiceRTASRReportVo, CallTypeEnum.DOUBLE_CALL.getValue(), MsgTypeEnum.NORMAL.getValue()); //异步
                        }catch (Exception e){
                            logger.error("--------->推送识别结果到分析服务器异常，sessionId:{}",voiceRTASRReportVo.getOut_id(),e);
                        }
                        logger.info("将words推送分析服务器入队时间："+(System.currentTimeMillis()-start1));



                    }
                } catch (Throwable e) {
                    //您自己的代码部分导致的异常，应该return false,这样消息不会被delete掉，而会根据策略进行重推
                    logger.error("----->接收ASR消息异常",e);
                    return true; //这些消息不太重要，不需要重推
                }
                //消息处理成功，返回true, SDK将调用MNS的delete方法将消息从队列中删除掉
                return true;
            });
            logger.info("------>初始化接收ASR实时消息队列完成");
        }catch (Exception e){
            logger.error("----->初始化接收ASR实时消息队列异常",e);
        }

    }


    /**
     * 初始化接收呼叫记录消息 ：注这里改成用http接受
     */
    @Deprecated
    public  void intiVoiceReport(){

		/*
		* TODO 将messageType和queueName替换成您需要的消息类型名称和对应的队列名称
        /*消息类型
        VoiceReport ：呼叫记录消息类型
        VoiceCallReport：呼叫中间状态消息类型
        VoiceRecordReport：呼叫录音记录消息
        VoiceRTASRReport：ASR实时消息类型
        */
        String messageType = "VoiceReport";//此处应该替换成相应产品的消息类型

        /**
         * 呼叫记录消息名称： Alicom-Queue-1733805875343381-VoiceReport
         * 呼叫中间状态消息名称： Alicom-Queue-1733805875343381-VoiceCallReport
         * asr 消息 ：Alicom-Queue-1733805875343381-VoiceRTASRReport
         */
        String queueName = "Alicom-Queue-1733805875343381-VoiceReport";//在云通信页面开通相应业务消息后，就能在页面上获得对应的queueName,每一个消息类型
        try {
            DefaultAlicomMessagePuller puller = new DefaultAlicomMessagePuller();
         //   puller.startReceiveMsg(AliyunAkInfo.accessKeyId,AliyunAkInfo.accessKeySecret, messageType, queueName, new MyMessageListener());
            System.out.println(" 初始化接收呼叫记录消息队列完成");
        }catch (Exception e){
            System.out.println(" 初始化接收呼叫记录消息队列异常");
            e.printStackTrace();

        }

    }

    /**
     * 初始化接收呼叫录音记录消息  注：这里改成用http接收
     */
    @Deprecated
    public  void intiVoiceRecordReport(){

		/*
		* TODO 将messageType和queueName替换成您需要的消息类型名称和对应的队列名称
        /*消息类型
        VoiceReport ：呼叫记录消息类型
        VoiceCallReport：呼叫中间状态消息类型
        VoiceRecordReport：呼叫录音记录消息
        VoiceRTASRReport：ASR实时消息类型
        */
        String messageType = "VoiceCallReport";//此处应该替换成相应产品的消息类型
        /**
         * 呼叫记录消息名称： Alicom-Queue-1733805875343381-VoiceReport
         * 呼叫中间状态消息名称： Alicom-Queue-1733805875343381-VoiceCallReport
         * asr 消息 ：Alicom-Queue-1733805875343381-VoiceRTASRReport
         */
        String queueName = "Alicom-Queue-1733805875343381-VoiceCallReport";//在云通信页面开通相应业务消息后，就能在页面上获得对应的queueName,每一个消息类型
        try {
            DefaultAlicomMessagePuller puller = new DefaultAlicomMessagePuller();
         //   puller.startReceiveMsg(AliyunAkInfo.accessKeyId, AliyunAkInfo.accessKeySecret, messageType, queueName, new MyMessageListener());
            logger.info(" 初始化接收呼叫录音记录消息队列完成");
        }catch (Exception e){
            logger.info(" 初始化接收呼叫录音记录消息队列异常");
            e.printStackTrace();
        }

    }


}
